package in.muton.edushare;

import java.util.ArrayList;
import java.util.List;

import org.apache.cayenne.access.DataContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.Request;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.WebSession;

import com.edushare.common.orm.CayenneORMInterface;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.vo.FilesUploaded;
import com.edushare.common.vo.Users;

/**
 * This custom session should be used wherever we need Wicket's WebSession object.
 * This will store all session level objects
 * @author Naishe
 * @version 0.0.1-SNAPSHOT
 */
public class EduShareSession extends WebSession {
	
	private static final long serialVersionUID = 2238961746596677943L;
	private ORMInterface cayenneORMInterface;
	private Users loggedInUser;
	private Log log = LogFactory.getLog(EduShareSession.class);
	private Users conflictingUser;
	private Integer filesUploadedThisSession = 0;
	private List<FilesUploaded> fileUploadedInLastUpload = new ArrayList<FilesUploaded>();
	private String feedbackMsg;
	
	public static EduShareSession get(){
		return (EduShareSession)Session.get();
	}
	
	public EduShareSession(Request request) {
		super(request);
		// TODO: initialize data (if any) when user interaction starts
	}
	
	/**
	 * Creates data for Cayenne Interface
	 * Returns Cayenne's DataContext object and stores it session
	 * @return DataContext
	 */
	public ORMInterface getSessionORMInterface(){
		synchronized(this){
			if(this.cayenneORMInterface==null){
				CayenneORMInterface cayenneIntf = new CayenneORMInterface();
				cayenneIntf.setDataContext(DataContext.createDataContext());
				this.cayenneORMInterface = cayenneIntf;
			}
		}
		return this.cayenneORMInterface;
	}
	
	/** Authentication */
	
	public void logInUser(Users usr){
		log.debug("logIn: #"+this.hashCode()+", str: "+this.toString());
		String uname = usr==null?"null":usr.getUserName();
		log.debug("Logging in as user name: " + uname);
		//check session clash
		if(loggedInUser!=null && usr !=null && loggedInUser.getUserId()!=usr.getUserId())
		{
			log.debug("Session overlap. " +
					"Logged-in user:"+loggedInUser.getUserName()+"["+loggedInUser.getUserId()+"], " +
					"logging-in as user "+usr.getUserName()+"["+usr.getUserId()+"].");
			this.conflictingUser = usr;
		}
		else
		{
			this.loggedInUser = usr;
			this.conflictingUser = null;
		}
	}
	
	public Users getConflictingUser(){
		return this.conflictingUser;
	}
	
	public Users getLoggedInUser(){
		log.debug("getlogIn: #"+this.hashCode()+", str: "+this.toString());
		String uname = this.loggedInUser==null?"null":this.loggedInUser.getUserName();
		log.debug("Logged in user name: " + uname);
//		Application.get().
		return this.loggedInUser;
	}
	
	public void logOutUser(){
		String uname = this.loggedInUser==null?"null":this.loggedInUser.getUserName();
		log.debug("Logging out user name: " + uname);
		this.loggedInUser = null;
	}
	
	public boolean isLoggedIn(){
		log.debug("getlogIn: #"+this.hashCode()+", str: "+this.toString());
		String uname = this.loggedInUser==null?"null":this.loggedInUser.getUserName();
		log.debug("Logged in user name: " + uname);
		
		if(this.loggedInUser==null)
			return false;
		else
			return true;
	}

	public boolean isAuthenticated() {
		// Currently authentication just means logged in
		return isLoggedIn();
	}

	public void invalidateConflictingUser() {
		this.conflictingUser = null;
	}

	/** Keeps track of files added by user in a given session */
	public void updateUploadedFileThisSession(int newUploads) {
		this.filesUploadedThisSession = this.filesUploadedThisSession + newUploads;
	}
	
	public int getFilesUploadedThisSession(){
		return this.filesUploadedThisSession;
	}

	public void setFileUploadedInLastUpload(FilesUploaded fileUploadedInLastUpload) {
		this.fileUploadedInLastUpload = new ArrayList<FilesUploaded>();
		if(fileUploadedInLastUpload!=null)
			this.fileUploadedInLastUpload.add(fileUploadedInLastUpload);
	}
	
	public void setFileUploadedInLastUpload(List<FilesUploaded> fileUploadedInLastUpload) {
		this.fileUploadedInLastUpload = fileUploadedInLastUpload;
	}

	public List<FilesUploaded> getFileUploadedInLastUpload() {
		return fileUploadedInLastUpload;
	}

	public void setFeedbackMsg(String feedbackMsg) {
		this.feedbackMsg = feedbackMsg;
	}

	public String getFeedbackMsg() {
		return this.feedbackMsg;
	}
	
}
